package battle_system

import (
	"game/app/actors/schemas"
	"gos/modules/logger"
)

// BattleBehaviorRound
type BattleBehaviorRound struct{}

type IBattleBehaviorRound interface {
	Start(state *schemas.MoveState, battle *schemas.Battle) bool
	Stop(state *schemas.MoveState, battle *schemas.Battle)
	OnDestory(state *schemas.MoveState, battle *schemas.Battle, stop bool)
	RoundUpdate(state *schemas.MoveState, battle *schemas.Battle) bool
	RoundBegin(state *schemas.MoveState, battle *schemas.Battle) bool
	RoundNormalAttack(state *schemas.MoveState, battle *schemas.Battle, first *schemas.BattleEntity, second *schemas.BattleEntity)
	RoundAttack(state *schemas.MoveState, battle *schemas.Battle)
	RoundEnd(state *schemas.MoveState, battle *schemas.Battle)
	RoundStop(state *schemas.MoveState, id int64, stop bool) bool
}

var BattleRound IBattleBehaviorRound = BattleBehaviorRound{}

// Start 开始战斗
func (s BattleBehaviorRound) Start(state *schemas.MoveState, battle *schemas.Battle) bool {
	battle.IsNowStart = true
	battle.IsBattle = true

	behavior, ok := BattleBehavior.GetBehavior(battle.A.Type)
	if !ok {
		return false
	}

	behavior.BeginBattle(state, battle.A)
	behavior, ok = BattleBehavior.GetBehavior(battle.B.Type)
	if !ok {
		return false
	}

	behavior.BeginBattle(state, battle.B)
	return true
}

// OnRoundStop 被动停止战斗
func (s BattleBehaviorRound) OnRoundStop(state *schemas.MoveState, battle *schemas.Battle, stop bool) bool {
	if state.GetTempBattle(battle.BattleId) {
		return false
	}

	s.Stop(state, battle)
	Battles.OnDestoryBattle(state, battle.A, battle.B, stop)
	state.AddDestoryBattle(battle.BattleId, battle)
	logger.WARN("回合被动结束战斗", battle.BattleId)
	return true
}

// RoundStop 停止战斗
func (s BattleBehaviorRound) RoundStop(state *schemas.MoveState, id int64, stop bool) bool {
	mapBattles := state.GetBattleEntityId(id)
	if mapBattles == nil {
		logger.ERR("回合战斗停止错误:", id)
		return false
	}

	for _, battle := range mapBattles {
		s.OnRoundStop(state, battle, stop)
	}
	return true
}

// RoundUpdate 回合更新
func (s BattleBehaviorRound) RoundUpdate(state *schemas.MoveState, battle *schemas.Battle) bool {
	if !battle.IsBattle {
		return false
	}

	battle.RoundCount++
	battle.HasRoundEvent = false
	if s.RoundBegin(state, battle) {
		s.RoundAttack(state, battle)
		s.RoundEnd(state, battle)
	}

	if !battle.IsBattle {
		//	如果战斗已经结束,需要A玩家下的所有的战斗全部结束
		if battle.A.IsDead {
			s.RoundStop(state, battle.A.Id, true)
		}

		//	如果战斗已经结束,需要B玩家下的所有的战斗全部结束
		if battle.B.IsDead {
			s.RoundStop(state, battle.B.Id, true)
		}

		// 结束当前AB战斗
		s.OnRoundStop(state, battle, true)
	}
	return true
}

// Stop 停止战斗
func (s BattleBehaviorRound) Stop(state *schemas.MoveState, battle *schemas.Battle) {
	if !battle.IsBattle {
		return
	}

	battle.IsBattle = false
}

// RoundBegin 回合开始
func (s BattleBehaviorRound) RoundBegin(state *schemas.MoveState, battle *schemas.Battle) bool {
	battle.IsInRound = true

	if battle.A == nil || battle.B == nil {
		s.Stop(state, battle)
		return false
	}

	if battle.A.IsDead || battle.B.IsDead {
		s.Stop(state, battle)
		return false
	}
	return true
}

// RoundNormalAttack 回合普攻
func (s BattleBehaviorRound) RoundNormalAttack(state *schemas.MoveState, battle *schemas.Battle, first *schemas.BattleEntity, second *schemas.BattleEntity) {
	damage := BattleBehaviEntity.CalDamage(state, first)
	BattleBehaviEntity.OnDamage(state, first, second, battle, damage)
}

// RoundAttack 回合攻击
func (s BattleBehaviorRound) RoundAttack(state *schemas.MoveState, battle *schemas.Battle) {
	if !battle.IsBattle {
		return
	}

	s.RoundNormalAttack(state, battle, battle.A, battle.B)
	s.RoundNormalAttack(state, battle, battle.B, battle.A)
}

const (
	MaxIdleFightNum = 8
)

// RoundEnd 回合战斗结束
func (s BattleBehaviorRound) RoundEnd(state *schemas.MoveState, battle *schemas.Battle) {
	if !battle.HasRoundEvent {
		battle.NoFightCount++
	} else {
		battle.NoFightCount = 0
	}

	if battle.NoFightCount >= MaxIdleFightNum {
		s.Stop(state, battle)
		logger.WARN("超过攻击范围最大次数,结束战斗:", battle.BattleId)
		return
	}

	if battle.A.IsDead {
		behavior, _ := BattleBehavior.GetBehavior(battle.A.Type)
		behavior.SetDead(state, battle.A)
	}

	if battle.B.IsDead {
		behavior, _ := BattleBehavior.GetBehavior(battle.B.Type)
		behavior.SetDead(state, battle.B)
	}

	if battle.A.IsDead || battle.B.IsDead {
		s.Stop(state, battle)
		return
	}
}

func (s BattleBehaviorRound) OnDestory(state *schemas.MoveState, battle *schemas.Battle, stop bool) {
	behavior, _ := BattleBehavior.GetBehavior(battle.A.Type)
	behavior.EndBattle(state, battle.A, stop)

	behavior, _ = BattleBehavior.GetBehavior(battle.B.Type)
	behavior.EndBattle(state, battle.B, stop)
}
